#!/usr/bin/env python3
"""
TellTech 定时任务服务
每天凌晨1点自动重置用户的免费调用次数
可作为独立服务运行
"""
import os
import sys
import time
import datetime
import threading
import signal
import subprocess
from pathlib import Path
from dotenv import load_dotenv
import MySQLdb
from MySQLdb import Error
from backend.app.utils.logger import logger

# 加载环境变量
load_dotenv()

# 获取项目根目录
PROJECT_ROOT = Path(__file__).parent.parent.parent.parent.parent.absolute()

# 数据库配置
DB_HOST = os.getenv("DB_HOST", "localhost")
DB_NAME = os.getenv("DB_NAME", "telltech")
DB_USER = os.getenv("DB_USER", "root")
DB_PASSWORD = os.getenv("DB_PASSWORD", "")

# 定时任务运行标志
timer_running = False
timer_thread = None
timer_initialized = False

def calculate_seconds_until_next_run(hour=1, minute=0):
    """计算距离下一次运行还有多少秒"""
    now = datetime.datetime.now()
    
    # 创建今天的目标时间点
    target_time = now.replace(hour=hour, minute=minute, second=0, microsecond=0)
    
    # 如果当前时间已经过了目标时间，则目标是明天的同一时间
    if now >= target_time:
        target_time += datetime.timedelta(days=1)
    
    # 计算时间差（秒）
    return (target_time - now).total_seconds()

def get_connection(database=None):
    """创建数据库连接"""
    try:
        connection = MySQLdb.connect(
            host=DB_HOST,
            user=DB_USER,
            passwd=DB_PASSWORD,
            db=database,
            charset='utf8mb4'
        )
        return connection
    except Error as e:
        logger.error(f"连接数据库时出错: {e}")
        return None

def reset_daily_free_calls():
    """重置所有用户的每日免费调用次数"""
    connection = get_connection(DB_NAME)
    if not connection:
        logger.error("无法连接到数据库，重置免费调用次数失败")
        return False
    
    try:
        cursor = connection.cursor()
        
        # 检查并更新需要重置的账户
        cursor.execute("""
        UPDATE vip_accounts 
        SET daily_free_calls = CASE 
            WHEN user_id IN (SELECT id FROM users WHERE role = 'superadmin') THEN -1
            WHEN user_id IN (SELECT id FROM users WHERE role = 'admin') THEN -1
            ELSE 100
        END,
        last_reset_date = CURRENT_DATE
        WHERE last_reset_date < CURRENT_DATE
        """)
        
        affected_rows = cursor.rowcount
        connection.commit()
        
        logger.info(f"已重置 {affected_rows} 个用户的每日免费调用次数")
        connection.close()
        return True
        
    except Error as e:
        logger.error(f"重置免费调用次数时出错: {e}")
        if connection:
            connection.rollback()
            connection.close()
        return False

def timer_task():
    """定时任务主函数"""
    global timer_running
    
    while timer_running:
        # 计算到凌晨1点的秒数
        seconds_to_wait = calculate_seconds_until_next_run(hour=1, minute=0)
        hours = int(seconds_to_wait / 3600)
        minutes = int((seconds_to_wait % 3600) / 60)
        
        logger.info(f"下一次重置将在 {hours} 小时 {minutes} 分钟后进行")
        
        # 等待到指定时间
        time.sleep(seconds_to_wait)
        
        # 执行重置
        if timer_running:
            logger.info("到达预定时间，开始执行定时任务")
            reset_daily_free_calls()
            
            # 短暂睡眠，避免在时间点附近多次运行
            time.sleep(5)

def start_timer():
    """启动定时器"""
    global timer_running, timer_thread, timer_initialized
    
    # 检查定时器是否已初始化，避免多次启动
    if timer_initialized:
        logger.info("定时器已初始化，不需要重复启动")
        return True
    
    if timer_running:
        logger.info("定时器已在运行")
        return True
    
    # 不再启动时执行重置操作
    # reset_daily_free_calls()
    
    # 启动定时线程
    timer_running = True
    timer_initialized = True
    timer_thread = threading.Thread(target=timer_task)
    timer_thread.daemon = True
    timer_thread.start()
    logger.info("定时重置服务已启动，将在每天凌晨1点执行")
    return True

def stop_timer():
    """停止定时器"""
    global timer_running, timer_thread, timer_initialized
    
    if not timer_running:
        logger.info("定时器未运行")
        return False
    
    timer_running = False
    timer_initialized = False
    if timer_thread:
        # 等待线程结束，最多等待1秒
        timer_thread.join(1.0)
        timer_thread = None
    logger.info("定时重置服务已停止")
    return True

def handle_exit(signum, frame):
    """处理退出信号"""
    logger.info("接收到退出信号，正在停止服务...")
    stop_timer()
    sys.exit(0)

def main():
    """主函数"""
    # 注册信号处理器
    signal.signal(signal.SIGINT, handle_exit)
    signal.signal(signal.SIGTERM, handle_exit)
    
    logger.info("开始运行TellTech定时重置服务")
    
    # 启动定时服务
    start_timer()
    
    # 保持主进程运行
    try:
        while True:
            time.sleep(60)
    except KeyboardInterrupt:
        logger.info("接收到中断信号，正在退出...")
        stop_timer()
    
    return 0

if __name__ == "__main__":
    sys.exit(main()) 